package com.xydtech.web.controller.system;

import com.alibaba.fastjson.JSON;
import com.xydtech.common.config.XydtechBusiPlatConfig;
import com.xydtech.common.constant.ShiroConstants;
import com.xydtech.common.constant.UserConstants;
import com.xydtech.common.core.controller.BaseController;
import com.xydtech.common.core.domain.AjaxResult;
import com.xydtech.common.core.domain.entity.SysMenu;
import com.xydtech.common.core.domain.entity.SysUser;
import com.xydtech.common.core.text.Convert;
import com.xydtech.common.utils.*;
import com.xydtech.common.utils.http.HttpClientUtil;
import com.xydtech.common.utils.rsa.RsaUtils;
import com.xydtech.common.utils.security.Md5Utils;
import com.xydtech.framework.jwt.auth.UsernameNoPasswordToken;
import com.xydtech.framework.shiro.service.SysPasswordService;
import com.xydtech.system.domain.SysMainPage;
import com.xydtech.system.service.ISysConfigService;
import com.xydtech.system.service.ISysMainPageService;
import com.xydtech.system.service.ISysMenuService;
import com.xydtech.system.service.ISysUserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * 首页 业务处理
 *
 * @author xydtech
 */
@Controller
public class SysIndexController extends BaseController {
    @Autowired
    private ISysMenuService menuService;

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private SysPasswordService passwordService;

    @Autowired
    private ISysMainPageService sysMainPageService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ISysUserService sysUserService;


    // 系统首页
    @GetMapping("/index")
    public String index(ModelMap mmap) {
        // 取身份信息
        SysUser user = getSysUser();
        Long deptId = user.getDeptId();
        // 根据用户id取出菜单
        List<SysMenu> menus = menuService.selectMenusByUser(user);
        mmap.put("menus", menus);
        mmap.put("user", user);
        mmap.put("sideTheme", configService.selectConfigByKey("sys.index.sideTheme", deptId));
        mmap.put("skinName", configService.selectConfigByKey("sys.index.skinName", deptId));
        Boolean footer = Convert.toBool(configService.selectConfigByKey("sys.index.footer", deptId), true);
        Boolean tagsView = Convert.toBool(configService.selectConfigByKey("sys.index.tagsView", deptId), true);
        mmap.put("footer", footer);
        mmap.put("tagsView", tagsView);
        mmap.put("mainClass", contentMainClass(footer, tagsView));
        mmap.put("copyrightYear", XydtechBusiPlatConfig.getCopyrightYear());
        mmap.put("demoEnabled", XydtechBusiPlatConfig.isDemoEnabled());
        mmap.put("isDefaultModifyPwd", initPasswordIsModify(user.getPwdUpdateDate()));
        mmap.put("isPasswordExpired", passwordIsExpiration(user.getPwdUpdateDate()));
        mmap.put("isMobile", ServletUtils.checkAgentIsMobile(ServletUtils.getRequest().getHeader("User-Agent")));
        mmap.put("systemName", XydtechBusiPlatConfig.getName());
        // 菜单导航显示风格
        String menuStyle = configService.selectConfigByKey("sys.index.menuStyle", deptId);
        // 移动端，默认使左侧导航菜单，否则取默认配置
        String indexStyle = ServletUtils.checkAgentIsMobile(ServletUtils.getRequest().getHeader("User-Agent")) ? "index" : menuStyle;

        // 优先Cookie配置导航菜单
        Cookie[] cookies = ServletUtils.getRequest().getCookies();
        for (Cookie cookie : cookies) {
            if (StringUtils.isNotEmpty(cookie.getName()) && "nav-style".equalsIgnoreCase(cookie.getName())) {
                indexStyle = cookie.getValue();
                break;
            }
        }
        String webIndex = "topnav".equalsIgnoreCase(indexStyle) ? "index-topnav" : "index";
        return webIndex;
    }

    /**
     * 自动登录系统首页
     *
     * @param mmap
     * @return java.lang.String
     * @throws
     * @Title: index
     * @author JHON
     * @Date 2022/5/6 13:36
     **/
    @GetMapping("/autoLogin")
    public String autoLongin(String u, ModelMap mmap) throws Exception {
        String logInfo = RsaUtils.decryptSecurityByPrivateKey(u);
        String loginName = JSON.parseObject(logInfo).getString("loginName");
        if (redisTemplate.opsForValue().get(UserConstants.AUTO_LOGIN_SIGN + loginName) == null) {
            mmap.put("errorMessage", "登录状态失效，请重新登录！");
            return "error/service";
        } else {
            String pwd = redisTemplate.opsForValue().get(UserConstants.AUTO_LOGIN_SIGN + loginName).toString();
            UsernamePasswordToken token = new UsernamePasswordToken(loginName, RsaUtils.decryptSecurityByPrivateKey(pwd));
            Subject subject = SecurityUtils.getSubject();
            subject.login(token);
            // 取身份信息
            SysUser user = getSysUser();
            Long deptId = user.getDeptId();
            // 根据用户id取出菜单
            List<SysMenu> menus = menuService.selectMenusByUser(user);
            mmap.put("menus", menus);
            mmap.put("user", user);
            mmap.put("sideTheme", configService.selectConfigByKey("sys.index.sideTheme", deptId));
            mmap.put("skinName", configService.selectConfigByKey("sys.index.skinName", deptId));
            Boolean footer = Convert.toBool(configService.selectConfigByKey("sys.index.footer", deptId), true);
            Boolean tagsView = Convert.toBool(configService.selectConfigByKey("sys.index.tagsView", deptId), true);
            mmap.put("footer", footer);
            mmap.put("tagsView", tagsView);
            mmap.put("mainClass", contentMainClass(footer, tagsView));
            mmap.put("copyrightYear", XydtechBusiPlatConfig.getCopyrightYear());
            mmap.put("demoEnabled", XydtechBusiPlatConfig.isDemoEnabled());
            mmap.put("isDefaultModifyPwd", initPasswordIsModify(user.getPwdUpdateDate()));
            mmap.put("isPasswordExpired", passwordIsExpiration(user.getPwdUpdateDate()));
            mmap.put("isMobile", ServletUtils.checkAgentIsMobile(ServletUtils.getRequest().getHeader("User-Agent")));
            mmap.put("systemName", XydtechBusiPlatConfig.getName());
            // 菜单导航显示风格
            String menuStyle = configService.selectConfigByKey("sys.index.menuStyle", deptId);
            // 移动端，默认使左侧导航菜单，否则取默认配置
            String indexStyle = ServletUtils.checkAgentIsMobile(ServletUtils.getRequest().getHeader("User-Agent")) ? "index" : menuStyle;

            // 优先Cookie配置导航菜单
            Cookie[] cookies = ServletUtils.getRequest().getCookies();
            if (cookies != null) {
                for (Cookie cookie : cookies) {
                    if (StringUtils.isNotEmpty(cookie.getName()) && "nav-style".equalsIgnoreCase(cookie.getName())) {
                        indexStyle = cookie.getValue();
                        break;
                    }
                }
            }
            String webIndex = "topnav".equalsIgnoreCase(indexStyle) ? "index-topnav" : "index";
            return webIndex;
        }

    }

    // 锁定屏幕
    @GetMapping("/lockscreen")
    public String lockscreen(ModelMap mmap) {
        mmap.put("user", getSysUser());
        ServletUtils.getSession().setAttribute(ShiroConstants.LOCK_SCREEN, true);
        return "lock";
    }

    // 解锁屏幕
    @PostMapping("/unlockscreen")
    @ResponseBody
    public AjaxResult unlockscreen(String password) {
        SysUser user = getSysUser();
        if (StringUtils.isNull(user)) {
            return AjaxResult.error("服务器超时，请重新登录");
        }
        if (passwordService.matches(user, password)) {
            ServletUtils.getSession().removeAttribute(ShiroConstants.LOCK_SCREEN);
            return AjaxResult.success();
        }
        return AjaxResult.error("密码不正确，请重新输入。");
    }

    // 切换主题
    @GetMapping("/system/switchSkin")
    public String switchSkin() {
        return "skin";
    }

    // 切换菜单
    @GetMapping("/system/menuStyle/{style}")
    public void menuStyle(@PathVariable String style, HttpServletResponse response) {
        CookieUtils.setCookie(response, "nav-style", style);
    }

    // 系统介绍
    @GetMapping("/system/main")
    public String main(ModelMap mmap) {
        SysMainPage mainPage = new SysMainPage();
        mainPage.setUserId(ShiroUtils.getUserId());
        SysMainPage mainPageInfo = sysMainPageService.selectMainPage(mainPage);
        mmap.put("mainPageInfo", mainPageInfo);
        mmap.put("version", XydtechBusiPlatConfig.getVersion());
        return "main";
    }

    // content-main class
    public String contentMainClass(Boolean footer, Boolean tagsView) {
        if (!footer && !tagsView) {
            return "tagsview-footer-hide";
        } else if (!footer) {
            return "footer-hide";
        } else if (!tagsView) {
            return "tagsview-hide";
        }
        return StringUtils.EMPTY;
    }

    // 检查初始密码是否提醒修改
    public boolean initPasswordIsModify(Date pwdUpdateDate) {
        // 取身份信息
        SysUser user = getSysUser();
        Long deptId = user.getDeptId();
        Integer initPasswordModify = Convert.toInt(configService.selectConfigByKey("sys.account.initPasswordModify", deptId));
        return initPasswordModify != null && initPasswordModify == 1 && pwdUpdateDate == null;
    }

    // 检查密码是否过期
    public boolean passwordIsExpiration(Date pwdUpdateDate) {
        // 取身份信息
        SysUser user = getSysUser();
        Long deptId = user.getDeptId();
        Integer passwordValidateDays = Convert.toInt(configService.selectConfigByKey("sys.account.passwordValidateDays", deptId));
        if (passwordValidateDays != null && passwordValidateDays > 0) {
            if (StringUtils.isNull(pwdUpdateDate)) {
                // 如果从未修改过初始密码，直接提醒过期
                return true;
            }
            Date nowDate = DateUtils.getNowDate();
            return DateUtils.differentDaysByMillisecond(nowDate, pwdUpdateDate) > passwordValidateDays;
        }
        return false;
    }


}
